<template>
  <div class="transfer">
    <div class="panel">
      <div class="title">
        待选区
        <!-- <el-checkbox v-model="checkedAll1" label="列表 1" size="large" /> -->
        <span class="ps1">{{ proportionScore1 }}</span>
      </div>
      <div class="tree">
        <el-input class="search" v-model="filterText1" placeholder="" :prefix-icon="Search" />
        <el-tree style="max-height: 400px;overflow: auto;" ref="treeRef1" :data="dataSource1" show-checkbox node-key="id"
          default-expand-all :expand-on-click-node="false" :props="defaultProps" :filter-node-method="filterNode1"
          @check="handleCheck1" />
      </div>
    </div>
    <div class="btn">
      <el-button @click="handleChange221" :disabled="disabled2" type="primary" icon="ArrowLeftBold" />
      <el-button @click="handleChange122" :disabled="disabled1" type="primary" icon="ArrowRightBold" />
    </div>
    <div class="panel">
      <div class="title">
        已选区
        <!-- <el-checkbox v-model="checkedAll2" label="列表 1" size="large" /> -->
        <span class="ps1">{{ proportionScore2 }}</span>
      </div>
      <div class="tree">
        <el-input class="search" v-model="filterText2" placeholder="" :prefix-icon="Search" />
        <el-tree style="max-height: 400px;overflow: auto;" ref="treeRef2" :data="dataSource2" show-checkbox node-key="id"
          default-expand-all :expand-on-click-node="false" :props="defaultProps" :filter-node-method="filterNode2"
          @check="handleCheck2" />
      </div>
    </div>
  </div>
  <!-- {{ dataSource1 }} -->
</template>
<script lang="ts" setup>
import _ from 'lodash'
import { ref, onMounted, reactive, defineProps, defineEmits, watch, nextTick, toRaw, computed } from 'vue'
import { useStore } from 'vuex'
import { Search } from '@element-plus/icons-vue'
import { ElTree } from 'element-plus'

interface Tree {
  [key: string]: any
}

interface listType {
  id: string,
  label: string,
  isMember?: boolean,
  children?: any[]
}

const emits = defineEmits(['change']);

const props = defineProps({
  value: {
    type: Array,
    default: () => [],
  },
  data: {
    type: Array,
    default: () => [],
  },
})

const defaultProps = {
  children: 'children',
  label: 'label',
}

const filterText1 = ref('')
const filterText2 = ref('')
const treeRef1 = ref<InstanceType<typeof ElTree>>()
const treeRef2 = ref<InstanceType<typeof ElTree>>()

const dataSource = ref([])
const dataSource1 = ref([])
const dataSource2 = ref([])

const disabled1 = computed(() => checkedMember.value.length === 0)
const disabled2 = computed(() => checked2.value.length === 0)

const checkedAll1 = ref(true)
const checkedAll2 = ref(false)

const checked1 = ref<string[]>([])
const checkedMember = ref<string[]>([])
const checked2 = ref<string[]>([])

/** 获取成员数据量 */
const getTotal = (data: any): number => {
  let sum = 0
  const totalSum = (list: any) => {
    const len = list.filter((item: any) => item.isMember).length
    sum += len;
    list.forEach((item: any) => {
      const children = _.get(item, 'children', [])
      if (!_.isEmpty(children)) totalSum(children)
    })
  }
  totalSum(data)
  return sum
}

// 1/10
const proportionScore1 = computed(() => `${checked1.value.length}/${getTotal(dataSource1.value)}`)
const proportionScore2 = computed(() => `${checked2.value.length}/${getTotal(dataSource2.value)}`)

// 左砖右
const handleChange122 = () => {
  let memberIds = checkedMember.value.map((item: listType) => item.id);
  let newArray = toRaw(dataSource1.value);
  let deleteItems: listType[] = [];
  let arr1 = [];
  let arr2 = [];
  deepFn(newArray, record => {
    if (memberIds.includes(record.id)) {
      deleteItems.push(record)
    }
  })
  deleteItems = _.uniqBy(deleteItems, 'memberId')
  // newArray.forEach((item: listType) => {
  //   if (item.label === '未分配' && item.children) {
  //     let len: number = item.children.length;
  //     for (let i = len - 1; i >= 0; i--) {
  //       let ele = item.children[i]
  //       if (memberIds.includes(ele.id)) {
  //         deleteItems.push(ele)
  //         item.children.splice(i, 1)
  //       }
  //     }
  //   }
  // })
  console.log("🚀 ~ file: customTransfer.vue:128 ~ newArray.forEach ~ newArray:", newArray)
  console.log("🚀 ~ file: customTransfer.vue:114 ~ handleChange122 ~ memberIds:", memberIds)
  console.log("🚀 ~ file: customTransfer.vue:116 ~ handleChange122 ~ newArray:", newArray)
  console.log("🚀 ~ file: customTransfer.vue:118 ~ handleChange122 ~ deleteItems:", deleteItems)
  const arr3 = dataSource2.value.concat(_.cloneDeep(deleteItems));
  dataSource2.value = arr3;
  checked2.value = arr3.map(item => item.memberId)
  // DeepRemoveById(dataSource1.value, memberIds, (record) => {
  //   console.log(record)
  //   if (record?.children?.length) {
  //     deepFn(record.children, (ele) => dataSource2.value.push(_.cloneDeep(ele)))
  //   } else {
  //     dataSource2.value.push(_.cloneDeep(record))
  //   }
  // })
}

// 右转左
const handleChange221 = () => {
  let deleteItems = dataSource2.value.filter((item: listType) => checked2.value.includes(item.id));
  let newData1 = dataSource1.value;
  newData1.forEach((item: listType) => {
    if (item.label === '未分配') {
      !item.children && (item.children = []);
      item.children = item.children?.concat(deleteItems);
    }
  })
  dataSource1.value = newData1;
  dataSource2.value = dataSource2.value.filter((item: listType) => !checked2.value.includes(item.id));
  checked2.value = [];
}

const deepFn = (arr: any[], fn: { (record: any): void; (record: any): void; (arg0: any): void }) => {
  arr.forEach((ele: { children: string | any[] }) => {
    if (ele?.children?.length) {
      deepFn(ele.children, fn)
    }
    fn(ele);
  });
}

const DeepRemoveById = (arr: string | any[], ids = [], fn: (arg0: any) => void) => {
  for (let i = 0; i < arr.length; i += 1) {
    if (ids.includes(arr[i].id)) {
      fn(arr[i]);
      delete arr[i];
      continue;
    }
    if (arr[i]?.children?.length) {
      DeepRemoveById(arr[i].children, ids, fn)
    }
  }
}

const filterNode1 = (value: string, data: Tree) => {
  if (!value) return true
  return data.label.includes(value)
}

const filterNode2 = (value: string, data: Tree) => {
  if (!value) return true
  return data.label.includes(value)
}

const getCheckMember = (ids: string[]) => {
  let members: listType[] = [];
  let loop = (data: listType) => {
    data.forEach((item: listType) => {
      if (item.isMember && ids.includes(item.id)) {
        members.push(toRaw(item))
      }
      if (item?.children?.length) {
        loop(item.children)
      }
    })
  }
  loop(dataSource1.value)
  console.log(members)
  checkedMember.value = members
}

const handleCheck1 = (checkedNodes: any, { checkedKeys, halfCheckedNodes, halfCheckedKeys }: any) => {
  console.log(checkedNodes, { checkedKeys, halfCheckedNodes, halfCheckedKeys })
  let _check: any[] = [];
  deepFn(dataSource1.value, (record: any) => {
    if (record.isMember && checkedKeys.includes(record.id)) _check.push(record.id)
  })
  checked1.value = _check;
  console.log(_check)
  getCheckMember(_check)
}

const handleCheck2 = (checkedNodes: any, { checkedKeys, halfCheckedNodes, halfCheckedKeys }: any) => {
  console.log(checkedNodes, { checkedKeys, halfCheckedNodes, halfCheckedKeys })
  let _check: any[] = [];
  deepFn(dataSource1.value, (record: any) => {
    if (record.isMember && checkedKeys.includes(record.id)) _check.push(record.id)
  })
  checked2.value = _check;
}


watch(() => props.data, (val: any) => {
  dataSource.value = _.cloneDeep(val);
  dataSource1.value = val;
  dataSource2.value = []
})

onMounted(() => {
  dataSource1.value = props.data as any;
  dataSource2.value = []
})

watch(dataSource2, (val) => {
  console.log('val', val)
  emits('change', val)
})
watch(filterText1, (val) => {
  treeRef1.value!.filter(val)
})

watch(filterText2, (val) => {
  treeRef2.value!.filter(val)
})
</script>

<style lang="less" scoped>
.transfer {
  display: flex;
  align-items: stretch;
  justify-content: center;

  .panel {
    flex-grow: 1;
    border: 0.0625rem solid #ebeef5;
    border-radius: 0.25rem;

    .title {
      font-size: 1rem;
      color: #303133;
      font-weight: 400;
      border-bottom: 1px solid #ebeef5;
      height: 40px;
      line-height: 40px;
      background-color: #f5f7fa;
      padding-left: 16px;
      position: relative;

      .ps1 {
        position: absolute;
        right: 0.9375rem;
        top: 50%;
        transform: translate3d(0, -50%, 0);
        color: #909399;
        font-size: 0.75rem;
        font-weight: 400;
      }
    }

    .tree {
      min-height: 300px;
    }
  }

  .btn {
    width: 162px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .tree {
    .search {
      margin: 15px 10px;
      width: calc(100% - 20px);
    }
  }
}
</style>